{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Database prototype\n",
    "\n",
    "Test DB functionality to store/update crater geometries. This is aimed at quickly debugging strategies for creating efficient storage/update routines since we will be storing millions of craters."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import os.path as op\n",
    "import csv\n",
    "import json\n",
    "from pathlib import Path\n",
    "\n",
    "from osgeo import ogr\n",
    "import numpy as np\n",
    "from tqdm import tqdm\n",
    "\n",
    "from sqlalchemy import create_engine, event, func\n",
    "from sqlalchemy import (Column, Integer, String, Float,\n",
    "                        ForeignKey)\n",
    "from sqlalchemy.sql import select\n",
    "from sqlalchemy.orm import sessionmaker, relationship\n",
    "from sqlalchemy.ext.declarative import declarative_base\n",
    "from sqlalchemy.schema import Index\n",
    "\n",
    "from geoalchemy2 import Geometry\n",
    "from geoalchemy2.functions import ST_Intersects\n",
    "\n",
    "\n",
    "# Set the declarative base to prep creation of SQL classes\n",
    "Base = declarative_base()\n",
    "iou_thresh = 0.75"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Define database classes"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "class Crater(Base):\n",
    "    \"\"\"Geometry and properties for a single crater\n",
    "    \n",
    "    Attributes\n",
    "    ----------\n",
    "    geometry: str\n",
    "        Polygon outlining the crater in WKT format.\n",
    "    confidence: float\n",
    "        ML model confidence that this is indeed a crater.\n",
    "    \"\"\"\n",
    "\n",
    "    __tablename__ = 'craters'\n",
    "    id = Column(Integer, primary_key=True)\n",
    "    geometry = Column(Geometry('POLYGON'))\n",
    "    confidence = Column(Float)\n",
    "    image_id = Column(Integer, ForeignKey('images.id'))\n",
    "\n",
    "    image = relationship('Image', back_populates='craters')\n",
    "    \n",
    "    # Add table index according to\n",
    "    #   https://stackoverflow.com/a/6627154\n",
    "    __table_args__ = (Index('geom_index', 'geometry', 'confidence'), )\n",
    "\n",
    "    def __repr__(self):\n",
    "        \"\"\"Define string representation.\"\"\"\n",
    "        return f'<Crater(confidence={self.confidence}, image={self.image})>'\n",
    "\n",
    "    \n",
    "class Image(Base):\n",
    "    \"\"\"Metadata for one satellite image\n",
    "    \n",
    "    Attributes\n",
    "    ----------\n",
    "    lon: float\n",
    "        Longitude of the image center\n",
    "    lat: float\n",
    "        Latitude of the image center\n",
    "    satellite: str\n",
    "        Satellite platform (e.g., 'MRO' or 'LROC')\n",
    "    camera: str\n",
    "        Imaging platform (e.g., 'CTX', 'HiRISE', or 'WAC')\n",
    "    pds_id: str\n",
    "        Planetary Data System unique ID of the image (e.g., 'B04_011293_1265_XN_53S071W')\n",
    "    \"\"\"\n",
    "\n",
    "    __tablename__ = 'images'\n",
    "    id = Column(Integer, primary_key=True)\n",
    "    lon, lat = Column(Float), Column(Float)\n",
    "    pds_id = Column(String)\n",
    "    satellite = Column(String)\n",
    "    camera = Column(String)\n",
    "    \n",
    "    # Add a relationship with the Crater class\n",
    "    craters = relationship('Crater', back_populates='image', cascade=\"all, delete, delete-orphan\")\n",
    "\n",
    "    def __repr__(self):\n",
    "        \"\"\"Define string representation.\"\"\"\n",
    "        return f'<Image({self.satellite}:{self.camera}, pds_id={self.pds_id})>'"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Create the database connection, add event listener"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "db_name = 'craters_v1'\n",
    "db_url = f'postgresql://postgres:postgres@localhost:5432/{db_name}'\n",
    "\n",
    "# Create database connection\n",
    "engine = create_engine(db_url, echo=False)\n",
    "Base.metadata.create_all(engine)\n",
    "Session = sessionmaker(bind=engine)\n",
    "session = Session()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "@event.listens_for(session, 'before_flush')\n",
    "def receive_before_flush(session, flush_context, instances):\n",
    "    \"Verify proposed database insertions using the 'before_flush' event.\"\n",
    "    for proposed_object in session.new:\n",
    "        \n",
    "        ##############################\n",
    "        # Look for repeat Image object\n",
    "        if type(proposed_object) == Image:\n",
    "            match = session.query(Image).filter(proposed_object.pds_id == Image.pds_id).one_or_none()\n",
    "            if match:\n",
    "                session.expunge(proposed_object)\n",
    "                print(f'Aborted insert for {proposed_object}. Image ID exists already.')\n",
    "            continue\n",
    "\n",
    "        #########################################################################################\n",
    "        # Identify if proposed craters should 1. not be inserted or 2. overwrite existing craters\n",
    "        \n",
    "        #stmt_confidence = proposed_object.confidence <= Crater.confidence\n",
    "        stmt_any_overlap = func.ST_Intersects(proposed_object.geometry, Crater.geometry)  # include or no?\n",
    "\n",
    "        # Conditions for match to existing crater (If met, skip insert)\n",
    "        intersection = func.ST_Area(func.ST_Intersection(proposed_object.geometry, Crater.geometry))\n",
    "        total_area = func.ST_Area(func.ST_Collect(proposed_object.geometry, Crater.geometry))\n",
    "        iou = intersection / (total_area - intersection)\n",
    "\n",
    "        # Run query against database\n",
    "        matches = session.query(Crater).filter(stmt_any_overlap, iou > iou_thresh).all()\n",
    "        if matches is None:\n",
    "            continue\n",
    "\n",
    "        # If crater overlaps found, determine if we should abort insert or overwrite.\n",
    "        for crater_match in matches:\n",
    "            print(f'Found {len(matches)} craters meeting IOU threshold...')\n",
    "\n",
    "            # Abort insert because new detection is not higher than existing\n",
    "            if proposed_object.confidence <= crater_match.confidence:\n",
    "                session.expunge(proposed_object)\n",
    "                print(f'Aborted insert for {proposed_object}.')\n",
    "                return\n",
    "\n",
    "            # Delete existing crater because new detection is higher confidence than existing\n",
    "            else:\n",
    "                session.delete(crater_match)\n",
    "                print(f'Overwriting {crater_match}.')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Add some data to the database (including repeat)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Committing craters...\n",
      "Aborted insert for <Image(MRO:CTX, pds_id=B04_011293_1265_XN_53S071W)>. Image ID exists already.\n",
      "Found 1 craters meeting IOU threshold...\n"
     ]
    },
    {
     "ename": "InvalidRequestError",
     "evalue": "Instance <Crater at 0x10a4d0dd8> is not present in this Session",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mInvalidRequestError\u001b[0m                       Traceback (most recent call last)",
      "\u001b[0;32m<ipython-input-5-68ac5eb3f965>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m\u001b[0m\n\u001b[1;32m      7\u001b[0m \u001b[0msession\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0madd_all\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mimage_1\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcrater_1\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcrater_2\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcrater_3\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m      8\u001b[0m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'Committing craters...'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 9\u001b[0;31m \u001b[0msession\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcommit\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m     10\u001b[0m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'...Commit complete.\\n'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     11\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;32m~/.virtualenvs/mars/lib/python3.7/site-packages/sqlalchemy/orm/session.py\u001b[0m in \u001b[0;36mcommit\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m   1034\u001b[0m                 \u001b[0;32mraise\u001b[0m \u001b[0msa_exc\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mInvalidRequestError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"No transaction is begun.\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m   1035\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 1036\u001b[0;31m         \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mtransaction\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcommit\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m   1037\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m   1038\u001b[0m     \u001b[0;32mdef\u001b[0m \u001b[0mprepare\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;32m~/.virtualenvs/mars/lib/python3.7/site-packages/sqlalchemy/orm/session.py\u001b[0m in \u001b[0;36mcommit\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m    501\u001b[0m         \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_assert_active\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mprepared_ok\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mTrue\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    502\u001b[0m         \u001b[0;32mif\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_state\u001b[0m \u001b[0;32mis\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0mPREPARED\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 503\u001b[0;31m             \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_prepare_impl\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m    504\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    505\u001b[0m         \u001b[0;32mif\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_parent\u001b[0m \u001b[0;32mis\u001b[0m \u001b[0;32mNone\u001b[0m \u001b[0;32mor\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mnested\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;32m~/.virtualenvs/mars/lib/python3.7/site-packages/sqlalchemy/orm/session.py\u001b[0m in \u001b[0;36m_prepare_impl\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m    480\u001b[0m                 \u001b[0;32mif\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msession\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_is_clean\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    481\u001b[0m                     \u001b[0;32mbreak\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 482\u001b[0;31m                 \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msession\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mflush\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m    483\u001b[0m             \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    484\u001b[0m                 raise exc.FlushError(\n",
      "\u001b[0;32m~/.virtualenvs/mars/lib/python3.7/site-packages/sqlalchemy/orm/session.py\u001b[0m in \u001b[0;36mflush\u001b[0;34m(self, objects)\u001b[0m\n\u001b[1;32m   2494\u001b[0m         \u001b[0;32mtry\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m   2495\u001b[0m             \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_flushing\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;32mTrue\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 2496\u001b[0;31m             \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_flush\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mobjects\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m   2497\u001b[0m         \u001b[0;32mfinally\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m   2498\u001b[0m             \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_flushing\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;32mFalse\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;32m~/.virtualenvs/mars/lib/python3.7/site-packages/sqlalchemy/orm/session.py\u001b[0m in \u001b[0;36m_flush\u001b[0;34m(self, objects)\u001b[0m\n\u001b[1;32m   2523\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m   2524\u001b[0m         \u001b[0;32mif\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdispatch\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mbefore_flush\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 2525\u001b[0;31m             \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdispatch\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mbefore_flush\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mflush_context\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mobjects\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m   2526\u001b[0m             \u001b[0;31m# re-establish \"dirty states\" in case the listeners\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m   2527\u001b[0m             \u001b[0;31m# added\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;32m~/.virtualenvs/mars/lib/python3.7/site-packages/sqlalchemy/event/attr.py\u001b[0m in \u001b[0;36m__call__\u001b[0;34m(self, *args, **kw)\u001b[0m\n\u001b[1;32m    320\u001b[0m             \u001b[0mfn\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m*\u001b[0m\u001b[0margs\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mkw\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    321\u001b[0m         \u001b[0;32mfor\u001b[0m \u001b[0mfn\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mlisteners\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 322\u001b[0;31m             \u001b[0mfn\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m*\u001b[0m\u001b[0margs\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mkw\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m    323\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    324\u001b[0m     \u001b[0;32mdef\u001b[0m \u001b[0m__len__\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;32m<ipython-input-4-189bfe72a37f>\u001b[0m in \u001b[0;36mreceive_before_flush\u001b[0;34m(session, flush_context, instances)\u001b[0m\n\u001b[1;32m     35\u001b[0m             \u001b[0;31m# Abort insert because new detection is not higher than existing\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     36\u001b[0m             \u001b[0;32mif\u001b[0m \u001b[0mproposed_object\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mconfidence\u001b[0m \u001b[0;34m<=\u001b[0m \u001b[0mcrater_match\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mconfidence\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 37\u001b[0;31m                 \u001b[0msession\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mexpunge\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mproposed_object\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m     38\u001b[0m                 \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34mf'Aborted insert for {proposed_object}.'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     39\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;32m~/.virtualenvs/mars/lib/python3.7/site-packages/sqlalchemy/orm/session.py\u001b[0m in \u001b[0;36mexpunge\u001b[0;34m(self, instance)\u001b[0m\n\u001b[1;32m   1826\u001b[0m         \u001b[0;32mif\u001b[0m \u001b[0mstate\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msession_id\u001b[0m \u001b[0;32mis\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mhash_key\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m   1827\u001b[0m             raise sa_exc.InvalidRequestError(\n\u001b[0;32m-> 1828\u001b[0;31m                 \u001b[0;34m\"Instance %s is not present in this Session\"\u001b[0m \u001b[0;34m%\u001b[0m \u001b[0mstate_str\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mstate\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m   1829\u001b[0m             )\n\u001b[1;32m   1830\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;31mInvalidRequestError\u001b[0m: Instance <Crater at 0x10a4d0dd8> is not present in this Session"
     ]
    }
   ],
   "source": [
    "image_1 = Image(lon=0, lat=1, satellite='MRO', camera='CTX', pds_id='B04_011293_1265_XN_53S071W')\n",
    "\n",
    "crater_1 = Crater(geometry='POLYGON((0 0,1 0,1 1,0 1,0 0))', confidence=0.8, image=image_1)\n",
    "crater_2 = Crater(geometry='POLYGON((2 2,3 2,3 3,2 3,2 2))', confidence=0.5, image=image_1)\n",
    "crater_3 = Crater(geometry='POLYGON((0 0.25,1 0.25,1 1.25,0 1.25,0 0.25))', confidence=0.9, image=image_1)  # Intersects with crater_1\n",
    "\n",
    "session.add_all([image_1, crater_1, crater_2, crater_3])\n",
    "print('Committing craters...')\n",
    "session.commit()\n",
    "print('...Commit complete.\\n')\n",
    "\n",
    "print('Attempting to add duplicate...')\n",
    "crater_repeat = Crater(geometry='POLYGON((0 0,1 0,1 1,0 1,0 0))', confidence=0.4, image=image_1)\n",
    "session.add_all([crater_repeat])\n",
    "session.commit()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Print out records as sanity check"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<Crater(confidence=0.999226907517258, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.998248205427578, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.997947264210877, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.99781997731258, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.997481727156054, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.997453851810966, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.99737273214768, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.996644421077627, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.996562936256443, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.99638590966003, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.996313798185973, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.995851535571652, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.995842788236813, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.995617531517192, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.995271282223159, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.99506414656473, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.994696746373906, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.994428759435067, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.994329793350269, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.994258667175884, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.994251970567982, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.994225821919959, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.994035019153274, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.99292451176164, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.992870568808474, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.991888476751147, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.991855911272844, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.991739348208948, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.991684258946874, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.991619472544377, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.990798776352333, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.990571446847235, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.990490530386373, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.989846359765489, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.989226140408369, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.989147093397251, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.98874320353141, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.988638330980063, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.988579571081969, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.988300791094986, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.988082738666738, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.987823390094198, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.987380809512167, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.987234091176191, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.987218679723025, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.987171562518189, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.987114998465972, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.986741551571646, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.986685398018847, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.986596416460287, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.986340786016451, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.986171308933437, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.986145595366916, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.985401158107176, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.985361066199773, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.98506499639426, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.983698168182977, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.983557913330493, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.983487483522242, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.983463467709589, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.98325388628313, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.982840329849179, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.982336220220616, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.981747572260216, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.981697404782935, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.980131516121856, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.979528590580746, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.979224636630524, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.978490579326968, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.978100326759126, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.97798219903825, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.977776291451566, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.97773239163302, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.977709405380031, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.977626964500701, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.977244144679817, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.97704407670201, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.976574173428436, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.975686961602442, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.97518316722457, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.973802161623592, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.972290036138449, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.97086490601568, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.970748009750667, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.969425051349808, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.969226891553126, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.96883077368526, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.967998101555332, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.967384657938181, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.966944172720571, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.966827035244375, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.966231007493213, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.965880412199096, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.965853102099986, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.965631670820831, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.965583475192966, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.965376262372441, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.964995726892075, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.964894807041422, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.964894786818797, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.964834254968619, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.96436309245905, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.964209135494799, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.964124726107133, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.963983328264202, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.963714033344745, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.963223962308865, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.962790341282247, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.962490539497726, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.962383659674205, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.961827754315472, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.96166648161154, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.961284015374527, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.961064610952536, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.960847832892427, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.960632214214199, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.960301052844659, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.95995482459125, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.957915397327665, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.957507599797561, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.955660277598315, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.955563842642238, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.95502787545398, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.954702192649567, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.954550679261117, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.95438617463779, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.953156927096993, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.952868763123064, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.95233916868004, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.952179776864991, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.95216603541906, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.951899835849136, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.95170470955404, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.951189335637428, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.951033560526864, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.950878476633262, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.94980170915633, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.949742600987936, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.949583363300896, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.949344016338265, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.947922958041695, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.945983633240164, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.945971826415448, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.945611071250957, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.943500023998417, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.94055182201854, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.940502282012774, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.940118383463773, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.939332801580091, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.937418863914675, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.937306487721108, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.937078932209238, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.936460961961181, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.934056947923314, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.933551990771261, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.933213337567743, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.932933983400558, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.932793553002224, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.930916696645787, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.930897890436787, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.930514470496844, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.930320335872876, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.929235054546251, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.928525614789676, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.924841268868914, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.924177849330027, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.923517617844066, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.92305609150267, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.921449304497751, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.920696921267767, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.91790636202306, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.917095101125169, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.916882955867801, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.914680732968818, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.913638471670781, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.912942580711258, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.909571218260876, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.909026382672932, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.90856095723495, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.908255998862183, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.907255645695201, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.90335075180464, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.902432883437271, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.898878209430255, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.895709576209592, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.893113316379713, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.892396382193382, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.890811363001207, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.89077939093347, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.890661218957101, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.890237410915037, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.889996949045509, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.887723938210967, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.887311729214993, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.885656536582699, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.885085379662271, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.884753478810195, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.883376060431243, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.881368054378773, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.880222487286937, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.87945670615987, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.879361131313602, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.878258132447294, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.874873853689874, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.874780937082747, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.873398045955779, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.872253526260056, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.871066783135171, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.866170834527709, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.86436059277742, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.863746829701456, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.863532157458236, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.863034039307761, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.861479108525634, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.861478235395868, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.858577547838761, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.858450861816619, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.858222254135417, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.858071466172009, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.85789810540792, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.856827095939942, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.852355384022606, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.851971083154457, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.85145553929563, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.850007409874707, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.849156505368269, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.848301638355726, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.847970504373896, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.847308163617089, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.84720945574946, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.846873836920114, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.846823373594082, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.846276657664216, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.843870592772509, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.840879687659407, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.84026546057792, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.839764604652114, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.838975442757541, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.83570525597345, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.833476913678569, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.832822255832015, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.83061102640467, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.827091201405701, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.825436134500263, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.824696187590215, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.82400900881014, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.823873362261392, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.823457148019042, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.822621781398878, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.815010116097872, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.814380147685543, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.8114205110301, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.806705933107547, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.800629080218076, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.79997900178564, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.795851607763283, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.795487714467862, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.7949324449757, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.793568737060223, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.791013243989564, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.789079845421647, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.788640018527462, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.786068681243613, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.779622626444441, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.778140513685495, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.776800619818566, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.774386302183196, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.772417844333084, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.77097019403255, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.769100080006153, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.76770591868537, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.763838865073298, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.763345134724014, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.759948973121187, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.759889098176301, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.758469829881978, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.756951504535585, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.756463516596539, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.754111533868737, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.753807665519521, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.74949230680899, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.748996943362744, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.748474340290803, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.742717618144435, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.742086917966102, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.737644766635812, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.733261553617318, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.72947188323776, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.727895640180823, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.72634284256141, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.724110203222305, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.721822843028321, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.715981161248928, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.715143084092364, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.710624949419202, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.706412813143534, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.706263759389173, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.703376126277134, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.699036154607898, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.694330571747817, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.688856853136653, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.687315720616891, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.686627308284633, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.682065088842255, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.676980169243286, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.675334278044381, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.672010310807307, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.664923511682443, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.663767842627404, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.662723705851013, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.659829791406882, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.657660863034948, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.654278210220845, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.652890937663728, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.649151532847966, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.646917403362605, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.644628423920063, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.640711252430299, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.637432171537387, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.635591540567978, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.62854414773819, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.626399470381971, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.624231012026576, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.61828928736269, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.61614928208495, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.599221670414985, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.590323878993904, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.584817361362249, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.583018016356285, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.580764289507317, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.575063020079728, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.552966704936165, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.552442787864655, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.546221094013233, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.54265731961181, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.541140684250383, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.538723299547099, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.537138399064545, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.533478185436635, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.531323691318058, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.526236747794286, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.515731039057428, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.50938574717539, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.508188458303255, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.506023837191806, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.500307397817246, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.494127353142572, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.474380319453186, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.473184882491242, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.47301167557122, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.47127579291865, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.470906241528815, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.470555972787445, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.467333931547647, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.456819597781864, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.455234114288299, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.454555694897178, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.434984232735434, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.432255432437145, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.419641470174946, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.417554706550734, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.415983339110167, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.404321941954959, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.402681656136145, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.381771805147859, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.373560350750238, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.367763051841842, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.3654853992619, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.361204588315294, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.351883375920676, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.343173852900966, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.340557854952483, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.338730898388972, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.32343217406667, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.317592296793529, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.307108697081138, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.291791730585417, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.278001055673196, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.271160684503296, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.268784405909196, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.268231588621651, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.263945646989541, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.258157905301482, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.247541216508209, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.247417412396163, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.241001348913343, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.233654924815071, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.230528195878453, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.228688705477048, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.228487502941979, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.2252616558235, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.208964910945492, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.199351000226653, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.196821732989648, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.175180799906785, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.174462090065343, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.169109108180962, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.168984628958656, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.159638834017827, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.159214148912373, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.125205033102876, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.124011016836353, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.112684819437721, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.109446556517351, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.0983431254214376, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.0939753437328822, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.091568290802322, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.0818293665243941, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.0757820669570538, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.0691056633109756, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.0659878078742142, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.0383509842557478, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.0357851301640378, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.0319036045907461, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.0250868624600225, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.0211425422836757, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.0170357088000199, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.0116830737811807, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.00601467711642567, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.00362062868756541, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.00056757392216189, image=<Image(MRO:CTX, pds_id=42)>)>\n"
     ]
    }
   ],
   "source": [
    "for crater in session.query(Crater).order_by(Crater.confidence.desc()):\n",
    "    print(crater)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Clear the DB\n",
    "for crater in session.query(Crater):\n",
    "    session.delete(crater)\n",
    "for image in session.query(Image):\n",
    "    session.delete(image)\n",
    "\n",
    "session.commit()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Stress test with a large set of random squares"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "3232it [00:14, 212.60it/s]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Found 1 craters meeting IOU threshold...\n",
      "Overwriting <Crater(confidence=0.502642571142911, image=<Image(MRO:CTX, pds_id=42)>)>.\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "3346it [00:15, 207.81it/s]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Found 1 craters meeting IOU threshold...\n",
      "Aborted insert for <Crater(confidence=0.4275887665505781, image=<Image(MRO:CTX, pds_id=42)>)>.\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "3736it [00:17, 207.82it/s]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Found 1 craters meeting IOU threshold...\n",
      "Aborted insert for <Crater(confidence=0.642929242354483, image=<Image(MRO:CTX, pds_id=42)>)>.\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "5348it [00:24, 212.25it/s]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Found 1 craters meeting IOU threshold...\n",
      "Aborted insert for <Crater(confidence=0.3823278064936011, image=<Image(MRO:CTX, pds_id=42)>)>.\n",
      "Found 1 craters meeting IOU threshold...\n",
      "Overwriting <Crater(confidence=0.202707126400347, image=<Image(MRO:CTX, pds_id=42)>)>.\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "5465it [00:24, 225.79it/s]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Found 1 craters meeting IOU threshold...\n",
      "Overwriting <Crater(confidence=0.332466387038364, image=<Image(MRO:CTX, pds_id=42)>)>.\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "6274it [00:28, 212.45it/s]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Found 1 craters meeting IOU threshold...\n",
      "Aborted insert for <Crater(confidence=0.6114541022487288, image=<Image(MRO:CTX, pds_id=42)>)>.\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "6432it [00:29, 218.59it/s]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Found 1 craters meeting IOU threshold...\n",
      "Overwriting <Crater(confidence=0.322867674133855, image=<Image(MRO:CTX, pds_id=42)>)>.\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "6524it [00:29, 222.72it/s]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Found 1 craters meeting IOU threshold...\n",
      "Aborted insert for <Crater(confidence=0.032625778122511995, image=<Image(MRO:CTX, pds_id=42)>)>.\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "7859it [00:35, 237.39it/s]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Found 1 craters meeting IOU threshold...\n",
      "Overwriting <Crater(confidence=0.0192029382223464, image=<Image(MRO:CTX, pds_id=42)>)>.\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "8708it [00:39, 215.22it/s]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Found 1 craters meeting IOU threshold...\n",
      "Aborted insert for <Crater(confidence=0.14257053529187147, image=<Image(MRO:CTX, pds_id=42)>)>.\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "9077it [00:41, 193.10it/s]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Found 1 craters meeting IOU threshold...\n",
      "Aborted insert for <Crater(confidence=0.09412299543958791, image=<Image(MRO:CTX, pds_id=42)>)>.\n",
      "Found 1 craters meeting IOU threshold...\n",
      "Overwriting <Crater(confidence=0.0511640186944237, image=<Image(MRO:CTX, pds_id=42)>)>.\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "9138it [00:41, 192.10it/s]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Found 1 craters meeting IOU threshold...\n",
      "Overwriting <Crater(confidence=0.874624118457979, image=<Image(MRO:CTX, pds_id=42)>)>.\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "9357it [00:42, 219.85it/s]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Found 1 craters meeting IOU threshold...\n",
      "Aborted insert for <Crater(confidence=0.06670927992016451, image=<Image(MRO:CTX, pds_id=42)>)>.\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "9630it [00:43, 219.01it/s]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Found 1 craters meeting IOU threshold...\n",
      "Overwriting <Crater(confidence=0.057020909398927, image=<Image(MRO:CTX, pds_id=42)>)>.\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "9867it [00:44, 234.59it/s]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Found 1 craters meeting IOU threshold...\n",
      "Aborted insert for <Crater(confidence=0.7781181214529727, image=<Image(MRO:CTX, pds_id=42)>)>.\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "9987it [00:45, 236.11it/s]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Found 1 craters meeting IOU threshold...\n",
      "Aborted insert for <Crater(confidence=0.421825421345691, image=<Image(MRO:CTX, pds_id=42)>)>.\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "10000it [00:45, 219.91it/s]\n"
     ]
    }
   ],
   "source": [
    "n_dummy_craters = 10000\n",
    "\n",
    "# Create random corner coordinate, size, and confidences\n",
    "ll = np.random.randint(low=0, high=1000, size=(n_dummy_craters, 2))\n",
    "size = np.random.exponential(scale=1, size=n_dummy_craters) + 1\n",
    "size = size.astype(np.int)\n",
    "confs = np.random.rand(n_dummy_craters)\n",
    "\n",
    "# Create/add image dummy to link dummy craters to\n",
    "image_dummy = Image(lon=0, lat=1, satellite='MRO', camera='CTX', pds_id='42')\n",
    "session.add(image_dummy)\n",
    "session.commit()\n",
    "\n",
    "# Add dummy craters\n",
    "for (x, y), w, c in tqdm(zip(ll, size, confs)):\n",
    "    temp_geom=f'POLYGON(({x} {y}, {x+w} {y}, {x+w} {y+w}, {x} {y+w}, {x} {y}))'\n",
    "    session.add(Crater(geometry=temp_geom, confidence=c, image=image_dummy))\n",
    "    session.commit()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Found 9982 of the 10000 attempted commits.\n",
      "<Crater(confidence=0.0387318499826185, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.936525140689017, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.18320792371987, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.672640217208064, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.708523744676866, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.671907881341991, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.539284935772952, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.515627718804522, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.334457654950846, image=<Image(MRO:CTX, pds_id=42)>)>\n",
      "<Crater(confidence=0.815040043179112, image=<Image(MRO:CTX, pds_id=42)>)>\n"
     ]
    }
   ],
   "source": [
    "crater_count = session.query(Crater).count()\n",
    "print(f'Found {crater_count} of the {n_dummy_craters} attempted commits.')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
